上一篇我們用Jaspersoft Studio設計好報表模板後,要如何用Java後端處理資料並且匯出Excel呢?
第一件事還是要先把JasperReports的dependency放好!
Maven dependency - Jasperreports
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.20.0</version>
</dependency>
一般來說,我們的資料來源常常是SQL查詢結果,但這是簡單的Demo,就先自己新增一些模擬數據。不過要把握以下原則:類別屬性的名稱與型別都要與Fields相同
Fields | 型別 |
---|---|
productName | String |
productPrice | Integer |
productNum | Integer |
priceSum | Integer |
import lombok.Data;
@Data
public class BBQSuppliesModel {
// 商品名稱
private String productName;
// 商品金額
private Integer productPrice;
// 商品數量
private Integer productNum;
// 購買金額小記
private Integer priceSum;
// 用Constructor方便創建物件以及計算購買金額小記
public BBQSuppliesModel(String productName, Integer productPrice, Integer productNum) {
this.productName = productName;
this.productPrice = productPrice;
this.productNum = productNum;
// 購買金額小記由 商品金額 * 商品數量 計算而來
this.priceSum = productPrice * productNum;
}
}
// 建立Demo資料
List<BBQSuppliesModel> bbqSuppliesModelList = new ArrayList<>();
BBQSuppliesModel bbqSuppliesModel1 = new BBQSuppliesModel("烤肉醬刷", 20, 3);
BBQSuppliesModel bbqSuppliesModel2 = new BBQSuppliesModel("烤肉醬", 200, 2);
BBQSuppliesModel bbqSuppliesModel3 = new BBQSuppliesModel("豬里肌", 150, 2);
BBQSuppliesModel bbqSuppliesModel4 = new BBQSuppliesModel("雪花牛", 250, 1);
BBQSuppliesModel bbqSuppliesModel5 = new BBQSuppliesModel("香菇", 120, 2);
bbqSuppliesModelList.add(bbqSuppliesModel1);
bbqSuppliesModelList.add(bbqSuppliesModel2);
bbqSuppliesModelList.add(bbqSuppliesModel3);
bbqSuppliesModelList.add(bbqSuppliesModel4);
bbqSuppliesModelList.add(bbqSuppliesModel5);
除了Fields,別忘了還有Parameters,一樣Java中型別需要與Parameters相同。
Parameters | 型別 |
---|---|
formatDate | String |
totalAmount | Integer |
REPORT_PARAMETERS_MAP
我們分別設定兩個Parameters,並放入REPORT_PARAMETERS_MAP中
// 設定報表參數,建立REPORT_PARAMETERS_MAP
Map<String, Object> parametersMap = new HashMap<>();
// 第一個parameter:購買日期
LocalDate localDate = new Date().toInstant()
.atZone(ZoneId.systemDefault()).toLocalDate();
// 格式化購買日期 yyyy-MM-dd
String formatDate = localDate
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
parametersMap.put("formatDate", formatDate);
// 第二個parameter:計算金額總計
Integer totalAmount = bbqSuppliesModelList.stream()
.mapToInt(BBQSuppliesModel::getPriceSum).sum();
parametersMap.put("totalAmount", totalAmount);
Java後端的部分能夠由JasperReports API輕鬆將DataSource放入報表模板,並編譯報表。
取得報表模板路徑,我放在Resources底下,因此路徑為String reportPath = "/Report/Jasper/demo.jrxml";
報表生命週期:在JasperReports 簡介曾提到報表的生命週期,我們目前只完成了「報表設計」,後面三步都能靠Java完成
jrxml
模板編譯成jasper文件(.jasper
).jasper
文件)和DataSource結合,回傳JasperPrint,包含了報表的所有資料和格式化結果// 匯出excel byte[]
String reportPath = "/Report/Jasper/demo.jrxml";
byte[] bytes = null;
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
// 以JasperCompileManager將jrxml模板編譯成jasper文件
JasperReport jasperReport = JasperCompileManager
// 我的方法放在JasperDemoFacadeImpl中
.compileReport(JasperDemoFacadeImpl.class.getResourceAsStream(reportPath));
// 將Java集合資料來源與Jasper報表進行綁定
JRDataSource dataSource = new JRBeanCollectionDataSource(bbqSuppliesModelList);
// 將資料填入報表
JasperPrint print = JasperFillManager
.fillReport(jasperReport, parametersMap, dataSource);
// 匯出XLSX
JRXlsxExporter exporter = new JRXlsxExporter();
exporter.setExporterInput(new SimpleExporterInput(print));
exporter
.setExporterOutput(new SimpleOutputStreamExporterOutput(byteArrayOutputStream));
exporter.exportReport();
bytes = byteArrayOutputStream.toByteArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
List<BBQSuppliesModel>
有多少資料而增長分頁功能通常是在pdf或word才需要的,以這個範例來說不適合,我們可以透過勾選「ignore pagination」告訴JasperReports這個報表不要分頁,再匯出就看起來比較正常了。
今天先到這啦,這篇只是範例,下一篇將嘗試以SQL查詢簡單的DB來實作匯出pdf